<template>
  <div class="blog-article">
    <el-card class="box-card">
      <!-- 搜索栏 -->
      <div class="search-bar">
        <el-form :inline="true" :model="searchForm">
          <el-form-item>
            <el-input
              v-model="searchForm.title"
              placeholder="文章标题"
              clearable
              @keyup.enter.native="handleSearch"
            />
          </el-form-item>
          <el-form-item>
            <el-select v-model="searchForm.categoryId" placeholder="文章分类" clearable>
              <el-option
                v-for="item in categoryOptions"
                :key="item.id"
                :label="item.name"
                :value="item.id"
              />
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="handleSearch">搜索</el-button>
            <el-button type="success" @click="handleAdd">新增文章</el-button>
          </el-form-item>
        </el-form>
      </div>

      <!-- 数据表格 -->
      <el-table
        v-loading="loading"
        :data="articleList"
        border
        style="width: 100%"
        row-key="id"
      >
        <el-table-column prop="title" label="标题" min-width="200" show-overflow-tooltip>
          <template slot-scope="scope">
            <el-link type="primary" @click="showDrawer(scope.row)">{{ scope.row.title }}</el-link>
          </template>
        </el-table-column>
        <el-table-column label="分类" width="120">
          <template slot-scope="scope">
            {{ getCategoryName(scope.row.categoryId) }}
          </template>
        </el-table-column>
        <el-table-column prop="status" label="状态" width="100">
          <template slot-scope="scope">
            <el-tag :type="scope.row.status === 1 ? 'success' : 'info'">
              {{ scope.row.status === 1 ? '已发布' : '草稿' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="viewCount" label="浏览量" width="100" />
        <el-table-column prop="likeCount" label="点赞数" width="100" />
        <el-table-column prop="createTime" label="创建时间" width="180">
          <template slot-scope="scope">
            {{ formatDateTime(scope.row.createTime) }}
          </template>
        </el-table-column>
        <el-table-column label="操作" width="250" fixed="right">
          <template slot-scope="scope">
            <el-button
              type="text"
              size="small"
              @click="handleEdit(scope.row)"
            >编辑</el-button>
            <el-button
              type="text"
              size="small"
              @click="handleStatus(scope.row)"
            >{{ scope.row.status === 1 ? '下架' : '发布' }}</el-button>
            <el-button
              type="text"
              size="small"
              class="delete-btn"
              @click="handleDelete(scope.row)"
            >删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页 -->
      <div class="pagination-container">
        <el-pagination
          background
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :current-page="pageNo"
          :page-sizes="[10, 20, 50, 100]"
          :page-size="pageSize"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
        />
      </div>
    </el-card>

    <!-- 新增/编辑对话框 -->
    <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="800px">
      <el-form :model="form" :rules="rules" ref="form" label-width="100px">
        <el-form-item label="文章标题" prop="title">
          <el-input v-model="form.title" />
        </el-form-item>
        <el-form-item label="文章分类" prop="categoryId">
          <el-select v-model="form.categoryId" placeholder="请选择分类">
            <el-option
              v-for="item in categoryOptions"
              :key="item.id"
              :label="item.name"
              :value="item.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="文章内容" prop="content">
          <el-input type="textarea" v-model="form.content" :rows="10" />
        </el-form-item>
        <el-form-item label="文章状态" prop="status">
          <el-radio-group v-model="form.status">
            <el-radio :label="0">草稿</el-radio>
            <el-radio :label="1">发布</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="handleSubmit">确 定</el-button>
      </div>
    </el-dialog>

    <el-drawer :title="drawerArticle.title" :visible.sync="drawerVisible" direction="rtl" size="50%">
      <div style="padding: 20px;">
        <div v-html="drawerContentHtml" class="markdown-body"></div>
      </div>
    </el-drawer>
  </div>
</template>

<script>
import { getArticleList, addArticle, updateArticle, deleteArticle, updateArticleStatus } from '@/api/blog'
import { getCategoryList } from '@/api/blog'
import { marked } from 'marked'
import DOMPurify from 'dompurify'
import 'github-markdown-css/github-markdown.css'

export default {
  name: 'BlogArticle',
  data() {
    return {
      loading: false,
      pageNo: 1,
      pageSize: 10,
      total: 0,
      articleList: [],
      categoryOptions: [],
      searchForm: {
        title: '',
        categoryId: null
      },
      dialogVisible: false,
      dialogTitle: '新增文章',
      form: {
        id: null,
        title: '',
        categoryId: null,
        content: '',
        status: 0
      },
      rules: {
        title: [
          { required: true, message: '请输入文章标题', trigger: 'blur' },
          { min: 2, max: 100, message: '长度在 2 到 100 个字符', trigger: 'blur' }
        ],
        categoryId: [
          { required: true, message: '请选择文章分类', trigger: 'change' }
        ],
        content: [
          { required: true, message: '请输入文章内容', trigger: 'blur' }
        ]
      },
      drawerVisible: false,
      drawerArticle: {
        title: '',
        content: ''
      }
    }
  },
  created() {
    this.getCategoryOptions()
    this.getList()
  },
  methods: {
    async getCategoryOptions() {
      try {
        const res = await getCategoryList({ pageSize: 100 })
        this.categoryOptions = res.data.data.rows
      } catch (error) {
        console.error('获取分类列表失败:', error)
      }
    },
    async getList() {
      this.loading = true
      try {
        const params = {
          pageNo: this.pageNo,
          pageSize: this.pageSize,
          title: this.searchForm.title,
          categoryId: this.searchForm.categoryId
        }
        const res = await getArticleList(params)
        this.articleList = res.data.data.rows
        this.total = res.data.data.total
      } catch (error) {
        console.error('获取文章列表失败:', error)
      } finally {
        this.loading = false
      }
    },
    handleSearch() {
      this.pageNo = 1
      this.getList()
    },
    handleAdd() {
      this.dialogTitle = '新增文章'
      this.form = {
        id: null,
        title: '',
        categoryId: null,
        content: '',
        status: 0
      }
      this.dialogVisible = true
    },
    handleEdit(row) {
      this.dialogTitle = '编辑文章'
      this.form = { ...row }
      this.dialogVisible = true
    },
    async handleStatus(row) {
      try {
        const newStatus = row.status === 1 ? 0 : 1
        await updateArticleStatus(row.id, newStatus)
        this.$message.success(newStatus === 1 ? '发布成功' : '下架成功')
        this.getList()
      } catch (error) {
        console.error('更新状态失败:', error)
      }
    },
    async handleDelete(row) {
      try {
        await this.$confirm('确认删除该文章吗？', '提示', {
          type: 'warning'
        })
        await deleteArticle(row.id)
        this.$message.success('删除成功')
        this.getList()
      } catch (error) {
        if (error !== 'cancel') {
          console.error('删除文章失败:', error)
        }
      }
    },
    async handleSubmit() {
      try {
        await this.$refs.form.validate()
        if (this.form.id) {
          await updateArticle(this.form)
          this.$message.success('更新成功')
        } else {
          await addArticle(this.form)
          this.$message.success('添加成功')
        }
        this.dialogVisible = false
        this.getList()
      } catch (error) {
        console.error('提交失败:', error)
      }
    },
    handleSizeChange(val) {
      this.pageSize = val
      this.getList()
    },
    handleCurrentChange(val) {
      this.pageNo = val
      this.getList()
    },
    formatDateTime(val) {
      if (!val) return '';
      const date = new Date(val);
      return date.toLocaleString();
    },
    getCategoryName(categoryId) {
      if (!Array.isArray(this.categoryOptions)) return ''
      const item = this.categoryOptions.find(c => c.id === categoryId)
      return item ? item.name : ''
    },
    showDrawer(row) {
      this.drawerArticle = {
        title: row.title,
        content: row.content
      }
      this.drawerVisible = true
    }
  },
  computed: {
    drawerContentHtml() {
      return DOMPurify.sanitize(marked(this.drawerArticle.content || ''))
    }
  }
}
</script>

<style lang="scss" scoped>
.blog-article {
  .search-bar {
    margin-bottom: 20px;
  }
  .pagination-container {
    margin-top: 20px;
    text-align: right;
  }
  .delete-btn {
    color: #F56C6C;
  }
}

::v-deep .markdown-body {
  box-sizing: border-box;
  min-width: 200px;
  max-width: 100%;
  margin: 0 auto;
  font-size: 16px;
  line-height: 1.7;
  color: #24292e;
  background: #fff;
  padding: 16px;
  border-radius: 6px;
  border: 1px solid #e1e4e8;
}
</style> 
 
 
 